﻿using System;
using System.ComponentModel;
using System.Data.Entity;
using System.Linq;
using EntityFramework6._1Examples;
using EntityFramework6._1Examples.Data;

namespace EntityFramework6.Services
{
    class Program
    {
        static void Main(string[] args)
        {

            using (var context = new BookContext())
            {
                ReadAllBooks(context);

                EagerLoadBookAuthors(context);

                LazyLoadBookAuthors(context);

                LoadUsingSqlQuery(context);

                LoadDataUsingSqlFromMoreThanOneTable(context);

            }
            
            Console.ReadLine();
        }

        private static void LoadDataUsingSqlFromMoreThanOneTable(BookContext context)
        {
            // loads data to custom Dtos without tracking
            var authorsBooks =
                context.Database.SqlQuery<AuthorsBooks>("select distinct count(b.id) as TotalBooks, a.Name as Author  from Authors a  inner join BookAuthors ba on a.Id = ba.Author_Id inner join Books b on b.ID = ba.Book_ID group by a.Name");
            foreach (var authorBook in authorsBooks)
            {
                DumpAllProperties(authorBook);
            }
        }

        private static void LoadUsingSqlQuery(BookContext context)
        {
            var authors = context.Authors.SqlQuery("select * from Authors");
            foreach (var author in authors)
            {
                DumpAllProperties(author);
            }
        }

        private static void LazyLoadBookAuthors(BookContext context)
        {
            var books = from b in context.Books
                        select b;

            foreach (var book in books)
            {
                foreach (var author in book.Authors)
                {
                    DumpAllProperties(author);
                }
            }
        }

        private static void EagerLoadBookAuthors(BookContext context)
        {
            // Eager load the authers!!
            var books = from b in context.Books.Include(a => a.Authors)
                select b;

            foreach (var book in books)
            {
                foreach (var author in book.Authors)
                {
                    DumpAllProperties(author);
                }
            }
        }

        private static void ReadAllBooks(BookContext context)
        {
                var books = from b in context.Books
                    select b;

                foreach (var book in books)
                {
                    DumpAllProperties(book);
                }
        }

        private static void DumpAllProperties(object obj)
        {
            foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(obj))
            {
                //Console.WriteLine("->" + descriptor.PropertyType.FullName);

                if (!descriptor.PropertyType.IsValueType && descriptor.PropertyType.FullName!="System.String")
                {
                    //DumpAllProperties(descriptor);
                    // ignore it
                }
                else
                {
                    string name = descriptor.Name;
                    object value = descriptor.GetValue(obj);
                    Console.WriteLine("{0}={1}", name, value);
                }

            }
        }
    }
}
